//
// Stepper motor class
//
// ZJ Laczik
//
// 19/11/1998
//
// Revision history:
//

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>

#include <iostream>
#include <fstream>

//// #include "qapplication.h"
#include <QObject>
#include <QApplication>

// #include "../drivers/pp/pp.h"

#include "stepper.h"

Stepper::Stepper(QWidget *parent) : QObject(parent) {
//	ioperm(LPT_BASE,1,1);
	ppdev=open("/dev/zjl_pp",O_RDWR) ;
	if (ppdev==0) {
		std::cerr<<"zjl_pp: no such device"<<std::endl ;
		exit(0);
	}

	current_pos[X_AX] = current_pos[Y_AX] = current_pos[Z_AX] = 0;

	StopFlag = false ;
	pStopFlag = &StopFlag ;

  delay_res=100;
  init_usec_delay();
}

Stepper::~Stepper() {
//	ioperm(LPT_BASE,1,0);
	close(ppdev) ;
}
  
void Stepper::SetStopFlagPointer(bool * pSF)
{
	pStopFlag = pSF ;
}

void Stepper::StepRel(long int steps, int axes)
{
  long int i;

  space=STEP_SPACE_MAX;

	if (steps>0) {
		for (i=0; i<abs(steps); i++) {
			one_step(TRUE, axes);
			if (space>STEP_SPACE_MIN)
				space-=STEP_DEC ;
			if (*pStopFlag) break;
		}
	}
	else if (steps<0) {
		for (i=0; i<abs(steps)+100; i++) {
			one_step(FALSE, axes);
			if (space>STEP_SPACE_MIN)
				space-=STEP_DEC;
			if (*pStopFlag) break;
		}
		space=STEP_SPACE_MAX;
		for (i=0; i<100; i++) {
			one_step(TRUE, axes);
			if (space>STEP_SPACE_MIN)
				space-=STEP_DEC;
			if (*pStopFlag) break;
		}
	};
}

void Stepper::StepAbs(long int steps, int axes)
{
  StepRel(steps-current_pos[axes], axes);
}

long int Stepper::GetPos(int axes)
{
return current_pos[axes];
}

void Stepper::SetPos(long int newpos, int axes)
{
current_pos[axes] = newpos;
}

void Stepper::init_usec_delay()
{
  long int liTst,diff;
  struct timeval b,a;
  struct timezone d;

  delay_cal = 1;
  liTst = 1000000; 

  gettimeofday(&b,&d);
  usec_delay(liTst);
  gettimeofday(&a,&d);
  
  diff = 1000000*(a.tv_sec-b.tv_sec) + (a.tv_usec-b.tv_usec);
  
  delay_cal = liTst/diff;
}

inline void Stepper::usec_delay(long int usecs)
{
long int liLoop;

liLoop=(usecs*delay_cal)/delay_res;

while (liLoop) liLoop--;
}

void Stepper::one_step(BOOL forward, int axes)
{
static int cnt=0;

	if (forward) {
//		outb(0x02,0x378);
////		ioctl(ppdev,PP_SET_BIT,0);
	}
	else {
//		outb(0x00,0x378);
////		ioctl(ppdev,PP_CLEAR_BIT,0);
	}

    usec_delay(space);
//    outb(0x03,0x378);
////		ioctl(ppdev,PP_SET_BIT,axes);
    usec_delay(STEP_MARK);
//    outb(0x02,0x378);
////		ioctl(ppdev,PP_CLEAR_BIT,axes);


	if (forward)
		current_pos[axes]++ ;
	else
		current_pos[axes]-- ;

	if (!(current_pos[X_AX]%50) && !(current_pos[Y_AX]%50) && !(current_pos[Z_AX]%50)) {
		emit(Position(
			float(current_pos[X_AX])/10.0,
			float(current_pos[Y_AX])/10.0,
			float(current_pos[Z_AX])/10.0 ));
	}
	if (!((cnt++)%1000)) {
		qApp->processEvents();
	}
}









